library(readr)
df <- read_csv("prado_variables.csv")
## Rows: 7035 Columns: 13
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (7): tam_cat, orientacion, soporte_grp, tecnica, tipo_autor, fecha_cat, ...
## dbl (6): exito, razon, area, sop_montaje, serie, fecha_est
## 
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
df$exito <- as.factor(df$exito)
df$tam_cat <- factor(
  df$tam_cat,
  levels = c("0", "1-10", "11-98", "99", "+100"),
  ordered = TRUE
)
df$orientacion <- as.factor(df$orientacion)
df$soporte_grp <-as.factor(df$soporte_grp)
df$sop_montaje <-as.factor(df$sop_montaje)
df$tecnica <- as.factor(df$tecnica)
df$tipo_autor <- as.factor(df$tipo_autor)
df$serie <- as.factor(df$serie)
df$fecha_est <- as.integer(df$fecha_est)
df$fecha_cat <- factor(
  df$fecha_cat,
  levels = c("0", "1-10", "11-98", "99", "+100"),
  ordered = TRUE
)
df$tema <- as.factor(df$tema)

Empezamos el análisis descriptivo construyendo para cada variable, una tabla de frecuencias y el gráfico de barras correspondiente, la forma más directa de entender cómo se reparte la información dentro del conjunto de datos. Antes de comparar con la variable respuesta (exito) o plantear cualquier modelo, necesitamos saber qué categorías aparecen, con qué peso y si existe algún patrón evidente en la composición de la muestra.

Como control de calidad permite detectar problemas típicos en datos obtenidos por web scraping, como etiquetas duplicadas, niveles inesperados o valores codificados de manera especial.

Las frecuencias son necesarias para interpretar correctamente lo que venga después. Si tenemos una categoría muy mayoritaria cualquier resultado puede estar condicionado por esa dominancia. Tener la proporción de cada nivel ayuda a contextualizar comparaciones; no es lo mismo observar un patrón en una categoría con miles de obras que en otra con muy pocas.

Las clases minoritarias aun que ess habitual que algunas categorías tengan pocas observaciones.Si tenemos demasiados niveles con baja frecuencia hacen que los gráficos sean ilegibles y no podamos extraer conclusiones.

En resumen, trabajar variable por variable es una etapa imprescindible porque permite verificar la coherencia de las variables, comprender la estructura real de los datos y anticipar problemas derivados de categorías raras. Esto asegura que las comparaciones posteriores con exito sean interpretables, estables y defendibles.

#exito

table(df$exito)
## 
##    0    1 
## 6186  849
v <- "exito"
tab <- sort(table(df[[v]]), decreasing = TRUE)

names(tab)[names(tab) == "0"] <- "0 (no cumple)"
names(tab)[names(tab) == "1"] <- "1 (cumple)"

# gráfico
barplot(tab, las = 1, main = "¿Cumple la proporción áurea?", ylab = "frequencia")

area ¿???¿?¿? MIRAR LO DEL LOG

hist(log1p(df$area), breaks = "FD", main = "Histograma de log1p(area)", xlab = "log1p(area)")

plot(density(log1p(df$area)), main = "Densidad de log1p(area)", xlab = "log1p(area)")

## miramos la distribución de area y si esta sesgada Útil para ver si necesitas log(area+1) y detectar valores extremos.

hist(df$area, breaks=40, main="Histograma de área", xlab="area")

hist(log(df$area ), breaks=40, main="Histograma de log(area+1)", xlab="log(area)")

boxplot(df$area, main="Boxplot área", ylab="area")

boxplot(log(df$area), main="Boxplot log(area+1)", ylab="log(area+1)")

El área está muy sesgada a la derecha: la mayoría de obras tienen áreas pequeñas y hay pocas con áreas enormes (por eso el histograma “normal” queda aplastado y el boxplot de area sale con mil outliers).

Al hacer log(area) la distribución queda mucho más “normalita” (campana) y el boxplot se vuelve legible → para comparar áreas entre grupos (tema, técnica, éxito, etc.)

#tam_cat

table(df$tam_cat)
## 
##     0  1-10 11-98    99  +100 
##     0     0     0     0     0
v <- "tam_cat"
tab <- sort(table(df[[v]]), decreasing = TRUE)

# gráfico
barplot(tab, las = 1, main = "Tamaño", ylab = "frequencia")

#orientación

table(df$orientacion)
## 
##   cuadrado horizontal   vertical 
##         33       3001       4001
v <- "orientacion"
tab <- sort(table(df[[v]]), decreasing = TRUE)

# gráfico
barplot(tab, las = 1, main = "Orientación", ylab = "frequencia")

#soporte_grp

table(df$soporte_grp)
## 
##      Lienzo       Metal       Mural       Otros Tabla/Panel 
##        5542         154          50         138        1151
v <- "soporte_grp"
tab <- sort(table(df[[v]]), decreasing = TRUE)

# gráfico
barplot(tab, las = 1, main = "??¿?¿?", ylab = "frequencia")

#sop_montaje

table(df$sop_montaje)
## 
##    0    1 
## 6759  276
v <- "sop_montaje"
tab <- sort(table(df[[v]]), decreasing = TRUE)

names(tab)[names(tab) == "0"] <- "No ?¿?¿"
names(tab)[names(tab) == "1"] <- "Sí ?¿?¿?"

# gráfico
barplot(tab, las = 1, main = "Soportes", ylab = "frequencia")

#dummies *****

#tipo_autor

table(df$tipo_autor)
## 
## anonimo  hombre   mujer  varios 
##     661    6161      59     154
v <- "tipo_autor"
tab <- sort(table(df[[v]]), decreasing = TRUE)

# gráfico
barplot(tab, las = 1, main = "Tipo de Autor", ylab = "frequencia")

#serie

table(df$serie)
## 
##    0    1 
## 5628 1407
v <- "serie"
tab <- sort(table(df[[v]]), decreasing = TRUE)
names(tab)[names(tab) == "0"] <- "0 (No)"
names(tab)[names(tab) == "1"] <- "1 (Sí)"

# gráfico
barplot(tab, las = 1, main = "Forma parte de una serie", ylab = "frequencia")

#fecha_est. ###### LOG ?¿?¿=??

table(df$fecha_est)
## 
## 1125 1150 1205 1208 1217 1272 1286 1290 1294 1325 1345 1348 1356 1358 1360 1365 
##    6   19    1    1    1    1    1    2    1    3    1    1    1    1    3    2 
## 1368 1370 1371 1374 1375 1381 1385 1388 1394 1400 1402 1405 1406 1408 1410 1411 
##    1    2    2    1    1    1    1    1    1    1    1    1    2    1    3    4 
## 1412 1415 1418 1420 1422 1423 1425 1426 1428 1435 1436 1438 1440 1445 1446 1450 
##    1    1    3    1    3    1    1    3    1    1    1    7    6    2    1   15 
## 1452 1455 1458 1460 1462 1464 1465 1466 1468 1470 1471 1475 1476 1478 1480 1482 
##    2    2    1    3    1    1    6    1    2    2    1    3    5    3    6    1 
## 1483 1485 1488 1490 1492 1494 1495 1496 1497 1498 1500 1502 1503 1504 1507 1508 
##    5    5    4   28    5    2   24    7    1    5   22    1    1    2    3    1 
## 1510 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 
##   18    4    1    5    7   14   11   11    4   11    1    8    3    3    9   10 
## 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 
##   10    4    7    2    2    2    1    7    3    2    7    2    9    2   12    3 
## 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 
##    1    8    3    1   18    1  128    2    6    3    6   14    1    2    9    4 
## 1560 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 
##   10    5    2    3   13    9    8   10    3   16    3    5    2    3    5   33 
## 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 
##    5    5    1   18    1    4    4    8    8    6    2    8    3   44    1    7 
## 1593 1594 1595 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 
##    1    7    8    2    7    3   51    6   18   10   16   10    7   16   10    4 
## 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 
##   23   29   19   29    2   14   17   22   23   15   33    6   14    7   10   31 
## 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 
##   81   15   15   54   35   11   52   16   83   43   47   68   51    7   46   12 
## 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 
##   14   14   11   18   14    8    7   18  840   18   18    9    8   28   13   10 
## 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 
##   13    8   41    7   10   29   11   30    3   10   32    3   18    1    3    9 
## 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 
##    7   15   66    2    9    5   11    5    2    4   15    5   14   13   20    3 
## 1690 1691 1692 1693 1694 1695 1696 1697 1698 1700 1701 1702 1703 1704 1705 1708 
##   25    4    6    8    7   12    6   16   26   45    6    4    2    3    1    3 
## 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 
##    2    8    1    3    1    2    4    8    8    1    1    7    2    1   10   10 
## 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 
##   10   18    2    2    6    7    3    2    1    2    5    1    3    6    3    3 
## 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1754 1755 1756 1758 1759 1760 
##    5    1    2    5    4    2    2    4    1  150   12    1   12    5    9   12 
## 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 
##    2    3   25    7   16    3    8    8    4   21   16   17    8   12   23   29 
## 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 
##   14   31   12   15    4    7    6   16   26   33   25   31   13   16    7   22 
## 1793 1794 1795 1796 1797 1798 1799 1800 1802 1803 1804 1805 1806 1807 1808 1809 
##    5    5    9    2    2   11    3   24    3    2    3    4   13    3    4    1 
## 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 
##    4    2    5    6    9   19    7    2    8   10   10    2   14    3    1    6 
## 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 
##    4   14    7    6    9    1    6   10    4   15    3    3   10    6   19    5 
## 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 
##   12    4   10    9    6    3   16    9   43   10   27   19   14   38   31   16 
## 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 
##   37   12   38   11   49   10   55   27   60   18   16   17   25   29   49   22 
## 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 
##   33   50   37   60   45   16   94   58   32   20   81   52   39   70   20   21 
## 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 
##   49   23   50   11   14   48   16   30   10   15   21   46   13    8   13   13 
## 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1922 
##   17   13   29    9   26   13   14    8    8   23    6   14    9    5   18    9 
## 1923 1924 1925 1926 1927 1928 1929 1930 1932 1933 1934 1935 1936 1938 1940 1941 
##    1    8   22    3    2    6    9    6    1    2    1    3    2    2    6    2 
## 1943 1944 1945 1946 1947 1948 1950 1951 1952 1954 1955 1957 1990 
##    1    1    2    2    1    8    3    2    2    1    5    3    1
v <- "fecha_est"
tab <- sort(table(df[[v]]), decreasing = FALSE)

# gráfico
barplot(tab, las = 1, main = "Fecha Estimada", ylab = "frequencia")

#fecha_ancho

table(df$fecha_ancho)
## Warning: Unknown or uninitialised column: `fecha_ancho`.
## < table of extent 0 >
v <- "fecha_ancho"
tab <- sort(table(df[[v]]), decreasing = TRUE)

#tema

table(df$tema)
## 
##    bodegon_floral     caza_animales historia_alegoria         mitologia 
##               325               106               258               227 
##             otros   paisaje_lugares      proceso_obra         religioso 
##              1216               884               123              2512 
##     retrato_corte    vida_cotidiana 
##               995               389
v <- "tema"
tab <- sort(table(df[[v]]), decreasing = TRUE)

# gráfico
barplot(tab, las = 2, main = "Tema de la Obra", ylab = "frequencia")

#pairs

vars_num <- c( "area", "razon", "fecha_est")
vars_num <- vars_num[vars_num %in% names(df)]

df_num <- df[, vars_num, drop = FALSE]

set.seed(1)
idx <- sample(nrow(df_num), min(1000, nrow(df_num)))

pairs(df_num[idx, ],
      pch = 16, cex = 0.4,
      main = "Pairs: variables numéricas (muestra)")

panel.cor <- function(x, y, digits = 2, prefix = "", cex.cor = 1.2, ...) {
  oldusr <- par("usr")
  on.exit(par(usr = oldusr))     # <- así NO da warnings
  par(usr = c(0, 1, 0, 1))

  r <- suppressWarnings(cor(x, y, method = "spearman"))
  txt <- formatC(r, digits = digits, format = "f")
  text(0.5, 0.5, paste0(prefix, txt), cex = cex.cor)
}

pairs(df_num[idx, ],
      lower.panel = panel.smooth,
      upper.panel = panel.cor,
      pch = 16, cex = 0.4,
      main = "Pairs + Spearman")

En el gráfico Pairs + Spearman se aprecia, en primer lugar, que las variables de tamaño (alto, ancho y area) están fuertemente relacionadas entre sí. Natural; las obras con mayor altura tienden a tener mayor anchura, y el area al ser un producto de ambas concentra prácticamente la misma información. En términos de análisis esta “familia” de variables es redundante: si en fases posteriores se construyen modelos, conviene evitar incluir a la vez alto, ancho y area porque pueden introducir colinealidad (aportan información muy parecida).

En los paneles de dispersión se ve que razon no aumenta sistemáticamente con alto, ancho o area: hay obras grandes y pequeñas con proporciones similares. Esto es importante porque sugiere que la proporción del cuadro es relativamente independiente del tamaño; por tanto.

La relación entre razon y dist_phi_log muestra un patrón claramente no lineal esperable porque dist_phi_log es la distancia a la razón áurea: toma valores pequeños cuando razon está cerca de φ y crece cuando se aleja por encima o por debajo.

Por último, fecha_est no presenta asociaciones fuertes y lineales con las dimensiones ni con las medidas de proporción en esta exploración global, si existe algún efecto temporal, probablemente débil o condicionado por subgrupos más que por el año en sí.

Este mapa de calor resume las correlaciones de Spearman entre las variables numéricas (incluidas las dummies 0/1). Sirve para ver qué variables se mueven juntas y cuáles aportan información más independiente. Al ser Spearman (por rangos), es útil aunque haya asimetrías, outliers o relaciones no perfectamente lineales.

Lo más evidente es el bloque de correlaciones altas entre alto, ancho y area. 7

También se aprecia que las variables ligadas a la proporción áurea (por ejemplo razon y dist_phi_log) presentan una relación destacable entre sí, lo cual tiene sentido porque dist_phi_log se deriva directamente de razon como medida de “distancia” a φ. Por tanto, no deben interpretarse como dos fuentes independientes de información: si el objetivo es modelar o explicar “cercanía a la proporción áurea”, normalmente conviene trabajar o bien con razon o bien con dist_phi_log, según si queréis una medida directa de proporción o una medida de desviación respecto a φ.

En contraste, el resto de variables (por ejemplo fecha_est, serie, sop_montaje y las dummies tec_*) muestran, en general, correlaciones relativamente bajas con el bloque de tamaño y con las variables de proporción, lo que sugiere que aportan información distinta y que sus efectos, si existen, probablemente no se explican simplemente por “cuadros más grandes/pequeños” o por el periodo. Dentro del grupo tec_* pueden aparecer correlaciones negativas entre algunas técnicas, algo normal porque en la práctica muchas técnicas funcionan como alternativas (si predomina una, disminuye la presencia de otra), aunque en vuestro caso puede haber multietiqueta.

En resumen, este gráfico confirma dos decisiones metodológicas importantes: (1) reducir redundancia quedándonos con una sola variable de tamaño y evitando meter juntas variables derivadas entre sí; y (2) separar el análisis de “tamaño” del análisis de “proporción”, porque no parecen ser la misma dimensión del fenómeno. Esto deja el terreno preparado para comparar exito con variables interpretables (técnica, soporte, época, etc.) sin que los resultados estén dominados por dependencias matemáticas entre variables.

##totas vairables con la variable respuesta exito

#que variables influyen al exito , hay diferencias entre categorias

exito y area

boxplot(log1p(df$area) ~ df$exito,
        main = "Distribución de log(área+1) según cumplimiento de la condición áurea",
        xlab = "¿Cumple la condición áurea?",
        ylab = "log(área + 1)",
        las = 1)

df$exito_f <- factor(df$exito, levels = c(0, 1),
                     labels = c("No cumple", "Sí cumple"))

Se observan outliers de obras muy pequeñas y muy grandes en ambos grupos, pero al usar log(área+1) su efecto queda controlado; no conviene eliminarlos, solo revisar los casos más extremos por si hay medidas atípicas. La mediana de log(área+1) es algo mayor en el grupo que sí cumple (1) que en el que no cumple (0), aunque hay bastante solapamiento, por lo que el tamaño parece asociarse al éxito de forma leve.

fecha estimada y exito

boxplot((df$fecha_est) ~ df$exito,
        main = "Distribución de la fecha estimada según cumplimiento de la condición áurea",
        xlab = "¿Cumple la condición áurea?",
        ylab = "fecha estimada",
        las = 1)

tab <- table(df$tam_cat, df$exito)
prop <- prop.table(tab, 1)  # proporciones por fila (cada tam_cat suma 1)

Se observan outliers de fechas muy tempranas en ambos grupos (más visibles en el grupo 0), que conviene revisar como posibles estimaciones poco precisas o casos especiales, pero no eliminarlos sin justificación histórica. La distribución del grupo que sí cumple (1) aparece ligeramente desplazada a fechas más recientes (mediana más alta), aunque hay solapamiento, por lo que la fecha podría influir de forma débil en el éxito.

tamaño categorizado con exito

barplot(t(prop),
        beside = FALSE,
        ylim = c(0,1),
        main = "Distribución de exito dentro de cada tam_cat",
        xlab = "tam_cat",
        ylab = "Proporción",
        las = 1)
legend("topright", legend = colnames(prop), bty = "n")

Se aprecia que la proporción de “sí cumple” es menor en obras grandes y mayor en medianas/pequeñas, lo que sugiere que el tamaño categorizado podría influir en el éxito (aunque las diferencias no parecen enormes).

fecha estimada con exito

hist(df$fecha_est, breaks="FD", main="Distribución de fecha_est", xlab="año estimado")

# tamaño a lo largo del tiempo (con suavizado)
plot(df$fecha_est, log1p(df$area), pch=16, cex=0.3,
     xlab="fecha_est", ylab="log1p(area)",
     main="Tamaño (log) vs tiempo")
lines(lowess(df$fecha_est, log1p(df$area), f=0.3), lwd=2)

##orientación con exito

tab <- table(df$orientacion, df$exito_f)

cols <- c("red", "green")  # No cumple / Sí cumple

barplot(t(tab),
        beside = TRUE,
        col = cols,
        las = 1,
        main = "Éxito según orientación",
        xlab = "Orientación",
        ylab = "Número de obras")

legend("topleft",
       legend = colnames(tab),
       fill = cols,
       bty = "n",
       cex = 0.9)

La categoría “cuadrado” tiene muy pocas observaciones y no es fiable para concluir. Entre horizontal y vertical se ve una diferencia pequeña: ambas concentran la mayoría de casos y la proporción de “sí cumple” parece similar, por lo que la orientación por sí sola no parece influir mucho en el éxito.

soporte con exito

df$exito_f <- factor(df$exito, levels=c(0,1), labels=c("No cumple","Sí cumple"))
tab <- table(df$soporte_grp, df$exito_f)

rate <- tab[, "Sí cumple"] / rowSums(tab)
n <- rowSums(tab)

ord <- order(rate, decreasing=TRUE)
rate <- rate[ord]; n <- n[ord]

ylab2 <- names(rate)
ylab2 <- gsub("Papel/Vitela", "Papel/\nVitela", ylab2)
ylab2 <- gsub("Tabla/Panel", "Tabla/\nPanel", ylab2)

op <- par(no.readonly=TRUE)

par(mar=c(5, 11, 4, 2) + 0.1)   # margen izq razonable
xmax <- max(rate) * 1.35        # escala que se adapte a tus tasas
bp <- barplot(rate,
              horiz=TRUE,
              names.arg = ylab2,
              xlim = c(0, xmax),
              col="lightblue",
              las=1,
              cex.names=0.95,
              main="Tasa de cumplimiento áureo por soporte",
              xlab="P(Sí cumple)",
              ylab="")

# "Soporte" cerca, sin exagerar
mtext("Soporte", side=2, line=3)

text(x=rate, y=bp, labels=paste0("  n=", n), pos=4, cex=0.9)

par(op)

Se observan diferencias en la tasa de éxito por soporte: lienzo, mural y tabla/panel presentan tasas más altas, mientras que metal y “otros” muestran tasas más bajas, lo que sugiere que el soporte podría influir en el éxito. Aun así, varias categorías tienen n pequeño (p. ej., mural, papel/vitela, otros), por lo que esas diferencias deben interpretarse con cautela y confirmarse con un contraste/modelo.

soporte montaje con exito

# Etiquetas bonitas
df$exito_f <- factor(df$exito, levels = c(0,1),
                     labels = c("No cumple", "Sí cumple"))
df$sop_montaje_f <- factor(df$sop_montaje, levels = c(0,1),
                           labels = c("No montaje", "Sí montaje"))

tab <- table(df$sop_montaje_f, df$exito_f)

cols <- c("red", "green")  # No / Sí

barplot(t(tab),
        beside = TRUE,
        col = cols,
        las = 1,
        main = "Éxito según sop_montaje",
        xlab = "sop_montaje",
        ylab = "Número de obras")

legend("topright",
       legend = colnames(tab),
       fill = cols,
       bty = "n")

rate <- tab[, "Sí cumple"] / rowSums(tab)

barplot(rate,
        ylim = c(0,1),
        col = "lightblue",
        las = 1,
        main = "Tasa de cumplimiento áureo según sop_montaje",
        xlab = "sop_montaje",
        ylab = "P(Sí cumple)")

text(seq_along(rate), rate, labels = round(rate, 3), pos = 3)

tab
##             
##              No cumple Sí cumple
##   No montaje      5949       810
##   Sí montaje       237        39
round(prop.table(tab, 1), 3)  # proporciones por fila
##             
##              No cumple Sí cumple
##   No montaje     0.880     0.120
##   Sí montaje     0.859     0.141

La variable sop_montaje parece influir un poco: cuando la obra es “montaje”, el porcentaje que cumple la proporción áurea es 14.1%, y cuando no es montaje es 12.0% (o sea, en montaje se cumple algo más). La diferencia es pequeña y además hay muchísimas menos obras con montaje (276) que sin montaje (6759), así que no podemos asegurar que sea una diferencia “real” sin comprobarlo con un test/modelo.

# Etiquetas de exito
df$exito_f <- factor(df$exito, levels = c(0,1),
                     labels = c("No cumple","Sí cumple"))

# Serie como factor (con labels bonitos)
df$serie_f <- factor(df$serie, levels = c(0,1),
                     labels = c("No pertenece a serie", "Pertenece a serie"))

# Tabla serie x éxito
tab <- table(df$serie_f, df$exito_f)

# Proporciones dentro de cada serie (cada fila suma 1)
prop <- prop.table(tab, 1)

# Ordenar por tasa de "Sí cumple" (opcional)
rate <- prop[, "Sí cumple"]
ord <- order(rate, decreasing = TRUE)
prop <- prop[ord, , drop = FALSE]
n <- rowSums(tab)[ord]

# Colores fijos
cols <- c("red", "green")  # No cumple / Sí cumple

par(mar=c(8,4,4,2)+0.1)
bp <- barplot(t(prop),
              beside = FALSE,
              ylim = c(0,1),
              las = 2,
              col = cols,
              main = "Distribución de éxito dentro de cada grupo de serie",
              ylab = "Proporción",
              xlab = "Serie")

legend("topright",
       legend = c("No cumple","Sí cumple"),
       fill = cols,
       bty = "n")

# n encima de cada barra
text(x = bp, y = 1.02, labels = paste0("n=", n), xpd = TRUE, cex = 0.8)

# (Opcional) mirar tabla y proporciones
tab
##                       
##                        No cumple Sí cumple
##   No pertenece a serie      4972       656
##   Pertenece a serie         1214       193
round(prop, 3)
##                       
##                        No cumple Sí cumple
##   Pertenece a serie        0.863     0.137
##   No pertenece a serie     0.883     0.117

tipo de autor con exito

df$exito_f <- factor(df$exito, levels = c(0,1),
                     labels = c("No cumple","Sí cumple"))

tab <- table(df$tipo_autor, df$exito_f)
rate <- tab[, "Sí cumple"] / rowSums(tab)

barplot(rate, ylim=c(0,1), las=1, col="lightblue",
        main="Tasa de cumplimiento áureo por tipo de autor",
        ylab="P(Sí cumple)")
text(seq_along(rate), rate, labels=round(rate,3), pos=3, cex=0.8)

Se observan diferencias en la tasa de éxito según tipo de autor (más alta en “varios” y “mujer”, más baja en “anónimo”), lo que sugiere cierta asociación entre tipo de autor y cumplimiento áureo. Pero hay que tener en cuenta el tamaño muestral muy desigual (hombre n=6161 vs mujer n=59 y varios n=154): las tasas de “mujer” y “varios” son mucho menos estables y deben interpretarse con cautela.

si forma parte de una serie y exito

# Etiquetas
df$exito_f <- factor(df$exito, levels = c(0,1),
                     labels = c("No cumple","Sí cumple"))

df$serie_f <- factor(df$serie, levels = c(0,1),
                     labels = c("No pertenece a serie", "Pertenece a serie"))

tab <- table(df$serie_f, df$exito_f)
cols <- c("red", "green")  # No cumple / Sí cumple

# 1) UNA barra por etiqueta (apilada) con CONTEOS
barplot(tab,
        beside = FALSE,
        col = cols,
        las = 1,
        main = "Éxito según pertenencia a serie",
        xlab = "Serie",
        ylab = "Número de obras")

legend("topright",
       legend = colnames(tab),
       fill = cols,
       bty = "n")

tab
##                       
##                        No cumple Sí cumple
##   No pertenece a serie      4972       656
##   Pertenece a serie         1214       193
round(prop.table(tab, 1), 3)   # proporciones dentro de cada grupo de serie
##                       
##                        No cumple Sí cumple
##   No pertenece a serie     0.883     0.117
##   Pertenece a serie        0.863     0.137

Pertenecer a una serie parece estar asociado a un ligero aumento del éxito: las obras en serie cumplen un poco más (13.7%) que las que no pertenecen a serie (11.7%). La diferencia es pequeña pero consistente, y como ambos grupos tienen tamaños razonables (n=1407 en serie vs n=5628 fuera), es un patrón a tener en cuenta y que se puede confirmar con un test/modelo.

fecha estimada y exito

df$exito_f <- factor(df$exito, levels = c(0,1),
                     labels = c("No cumple","Sí cumple"))

boxplot(df$fecha_est ~ df$exito_f,
        main = "Fecha estimada según cumplimiento áureo",
        xlab = "¿Cumple?",
        ylab = "fecha_est (año)",
        las = 1)

Las obras que sí cumplen la condición áurea tienden a ser ligeramente más recientes (mediana algo más alta) que las que no cumplen, por lo que la fecha estimada podría estar asociada al éxito, aunque el solapamiento entre cajas es grande. Los outliers son pocas obras muy antiguas (sobre todo en “no cumple”); no se eliminarían por defecto, pero conviene revisarlas por si son fechas mal estimadas o casos especiales, y usar métodos robustos si afectan al modelo.

tema y exito

# Etiquetas bonitas para exito
df$exito_f <- factor(df$exito, levels = c(0,1),
                     labels = c("No cumple","Sí cumple"))

# Tabla tema × exito
tab <- table(df$tema, df$exito_f)

# Tasa de éxito por tema
rate <- tab[, "Sí cumple"] / rowSums(tab)
n <- rowSums(tab)

# Ordenar (elige UNA de estas dos)
ord <- order(rate, decreasing = TRUE)   # por tasa de éxito
# ord <- order(n, decreasing = TRUE)    # por tamaño muestral

rate <- rate[ord]
n <- n[ord]

# Línea base (tasa global)
p_global <- mean(df$exito_f == "Sí cumple")

# Plot horizontal para que se lean todos los temas
par(mar = c(5, 16, 4, 2) + 0.1)

bp <- barplot(rate,
              horiz = TRUE,
              xlim = c(0, 1),
              col = "lightblue",
              las = 1,
              main = "Tasa de cumplimiento áureo por tema",
              xlab = "P(Sí cumple)")

abline(v = p_global, lty = 2)

# Etiquetas con n
text(x = rate, y = bp, labels = paste0("n=", n), pos = 4, cex = 0.8)

par(mar = c(5,4,4,2) + 0.1)

Si la barra de un tema queda a la derecha de esa línea → ese tema tiene una tasa de éxito mayor que la media general. Si queda a la izquierda → menor que la media general. Se aprecian diferencias de tasa de éxito entre temas (algunas categorías quedan por encima y otras por debajo de la media general), lo que sugiere que el “tema” podría estar relacionado con el cumplimiento áureo. Pero hay que interpretar con mucha cautela los temas con n pequeño (p. ej., caza_animales n=106 o proceso_obra n=123), porque sus porcentajes pueden variar mucho por azar; las comparaciones más fiables son las de temas con n grande (p. ej., religioso n=2512, otros n=1216, retrato_corte n=995).

#SEGUIMOOOSOOSOSOSOOSOOSOSOO

##orientación con tam_cat

# ORIENTACION vs TAM_CAT  (barras 100% por tamaño)
tab <- table(df$orientacion, df$tam_cat)
tab  # conteos
##             
##              0 1-10 11-98 99 +100
##   cuadrado   0    0     0  0    0
##   horizontal 0    0     0  0    0
##   vertical   0    0     0  0    0
prop_col <- prop.table(tab, 2)  # proporciones dentro de cada tam_cat
round(prop_col, 3)
##             
##              0 1-10 11-98 99 +100
##   cuadrado                       
##   horizontal                     
##   vertical
cols <- c("skyblue3","orange2","gray50")  # vertical / horizontal / cuadrado (ajusta si quieres)

barplot(prop_col,
        beside = FALSE,
        ylim = c(0, 1),
        las = 1,
        col = cols,
        main = "Orientación dentro de cada tamaño (tam_cat)",
        xlab = "Tamaño (tam_cat)",
        ylab = "Proporción")

legend("topright", legend = rownames(prop_col), fill = cols, bty = "n")

En los tres tamaños (pequeño, mediano y grande) prácticamente no aparecen obras “cuadrado” (proporción casi 0), así que la orientación dominante es horizontal/vertical.

Sí hay diferencias entre categorías: en “mediano” aumenta la proporción de verticales (y bajan las horizontales) respecto a “grande” y “pequeño”, pero las diferencias no parecen enormes (el patrón general se mantiene).

orientación con tam_cat i con exito

# Factores bonitos
df$exito_f <- factor(df$exito, levels=c(0,1), labels=c("No cumple","Sí cumple"))

# Asegura orden (opcional)
df$tam_cat <- factor(df$tam_cat, levels=c("pequeno","mediano","grande"))
df$orientacion <- factor(df$orientacion, levels=c("horizontal","vertical","cuadrado"))

# Tabla 3D: orientacion x tam_cat x exito
tab3 <- table(df$orientacion, df$tam_cat, df$exito_f)

# Colores fijos para éxito
cols_ex <- c("red","green")  # No cumple / Sí cumple

op <- par(no.readonly = TRUE)
par(mfrow=c(1,3), mar=c(7,4,4,1)+0.1)  # 3 paneles

for(tam in levels(df$tam_cat)){

  tab_tam <- tab3[, tam, ]               # orientacion x exito
  prop_tam <- prop.table(tab_tam, 1)     # dentro de cada orientacion suma 1

  bp <- barplot(t(prop_tam),
                beside=FALSE,
                ylim=c(0,1),
                las=2,
                col=cols_ex,
                main=paste("tam_cat =", tam),
                ylab="Proporción",
                xlab="Orientación")

  # n por orientación (tamaño muestral)
  n <- rowSums(tab_tam)
  text(x=bp, y=1.02, labels=paste0("n=", n), xpd=TRUE, cex=0.8)
}

legend("topright",
       legend=c("No cumple","Sí cumple"),
       fill=cols_ex, bty="n", inset=c(-0.15,0))

par(op)

En los tres tamaños (pequeño/mediano/grande) domina claramente el “No cumple” (rojo): las tasas de “Sí cumple” (verde) son bajas en general, así que no parece que el tamaño por sí solo cambie mucho el éxito.

Dentro de cada tamaño, la orientación sí marca pequeñas diferencias: en “grande” la orientación vertical parece tener una proporción de “Sí cumple” algo mayor que horizontal, pero ojo con “cuadrado” porque tiene muy pocas observaciones (n muy pequeño) y esa barra no es fiable para comparar.

serie y soporte_grp

# Serie con etiquetas bonitas (si ya la tienes, puedes saltarte esto)
df$serie_f <- factor(df$serie, levels = c(0,1),
                     labels = c("No pertenece a serie", "Pertenece a serie"))

# Tabla: soporte (filas) x serie (columnas)
tab <- table(df$soporte_grp, df$serie_f)
tab  # conteos
##              
##               No pertenece a serie Pertenece a serie
##   Lienzo                      4419              1123
##   Metal                        118                36
##   Mural                          4                46
##   Otros                        114                24
##   Tabla/Panel                  973               178
par(mar=c(6,4,4,12)+0.1, xpd=NA)  # MÁS margen derecho + permitir dibujar fuera
bp <- barplot(prop,
              beside = FALSE,
              ylim = c(0,1),
              las = 1,
              col = cols,
              main = "Soporte dentro de cada grupo de serie",
              xlab = "Serie",
              ylab = "Proporción")

# n total por cada grupo de serie
n_serie <- colSums(tab)
text(x = bp, y = 1.02, labels = paste0("n=", n_serie), cex = 0.85)

# Leyenda a la derecha (no se corta)
legend("topright",
       inset = c(-0.35, 0),
       legend = rownames(prop),
       fill = cols,
       bty = "n",
       cex = 0.9)

##soporte grp serie y exito

# Factores bonitos
df$exito_f <- factor(df$exito, levels=c(0,1), labels=c("No cumple","Sí cumple"))
df$serie_f <- factor(df$serie, levels=c(0,1),
                     labels=c("No pertenece a serie","Pertenece a serie"))

# Tabla 3D: soporte x serie x exito
tab3 <- table(df$soporte_grp, df$serie_f, df$exito_f)

# Orden soportes por nº total (para que sea estable y legible)
tot_sop <- apply(tab3, 1, sum)
tab3 <- tab3[order(tot_sop, decreasing=TRUE), , , drop=FALSE]

# Etiquetas con saltos de línea
ylab2 <- rownames(tab3)
ylab2 <- gsub("Papel/Vitela", "Papel/\nVitela", ylab2)
ylab2 <- gsub("Tabla/Panel", "Tabla/\nPanel", ylab2)

cols <- c("red", "green")  # No cumple / Sí cumple

op <- par(no.readonly=TRUE)

# 3 columnas: panel izq, panel der, columna de leyenda
layout(matrix(c(1,2,3), nrow=1), widths=c(1,1,0.55))

for (s in levels(df$serie_f)) {

  tab_s <- tab3[, s, , drop=FALSE][,,1:2]   # soporte x exito
  tab_s <- tab_s[, c("No cumple","Sí cumple")]

  prop_s <- prop.table(tab_s, 1)           # cada soporte suma 1 (proporción dentro de soporte)
  prop_s[is.na(prop_s)] <- 0
  n <- rowSums(tab_s)

  par(mar=c(5, 9.5, 3.5, 2) + 0.1, xpd=NA)

  bp <- barplot(t(prop_s),
                horiz=TRUE,
                names.arg=ylab2,
                col=cols,
                xlim=c(0,1),
                las=1,
                cex.names=0.9,
                main=paste("Serie:\n", s),
                xlab="Proporción",
                border=NA)

  axis(1, at=seq(0,1,0.2))
  box()

  # n al final de cada barra (a la derecha)
  text(x=1.02, y=bp, labels=paste0("n=", n), pos=4, cex=0.8)
}

# Columna 3: leyenda limpia
par(mar=c(0,0,0,0))
plot.new()
legend("center",
       legend=c("No cumple","Sí cumple"),
       fill=cols,
       bty="n",
       cex=1)

par(op)

serie i fecha estimada

df$serie_f <- factor(df$serie, levels = c(0,1),
                     labels = c("No pertenece a serie", "Pertenece a serie"))

par(mar = c(6,6,4,2) + 0.1)

boxplot(fecha_est ~ serie_f, data = df,
        col = c("gray85","lightblue"),
        pch = 16, cex = 0.7,
        main = "Fecha estimada según pertenencia a serie",
        xlab = "Serie",
        ylab = "fecha_est (año)",
        las = 1)

# puntos con transparencia + muestra (para que se vea bien)
set.seed(1)
m <- min(800, nrow(df))
idx <- sample(seq_len(nrow(df)), m)

stripchart(df$fecha_est[idx] ~ df$serie_f[idx],
           vertical = TRUE, method = "jitter",
           pch = 16, cex = 0.35,
           col = adjustcolor("black", alpha.f = 0.25),
           add = TRUE)

grid(nx = NA, ny = NULL)

#fecha estimada serie y exito

# Factores bonitos
df$exito_f <- factor(df$exito, levels = c(0,1),
                     labels = c("No cumple","Sí cumple"))

df$serie_f <- factor(df$serie, levels = c(0,1),
                     labels = c("No pertenece a serie", "Pertenece a serie"))

cols <- c("red", "green")  # No cumple / Sí cumple

op <- par(no.readonly = TRUE)

par(mfrow = c(1,2), mar = c(6,5,4,1) + 0.1, oma = c(0,0,2,0))

for (s in levels(df$serie_f)) {
  sub <- df[df$serie_f == s, , drop = FALSE]

  bp <- boxplot(fecha_est ~ exito_f, data = sub,
                col = cols,
                main = paste("Serie:", s),
                xlab = "Éxito",
                ylab = "fecha_est (año)",
                las = 1,
                outline = TRUE)

  grid(nx = NA, ny = NULL)

  # n encima de cada caja
  text(x = 1:2, y = par("usr")[4], labels = paste0("n=", bp$n),
       xpd = TRUE, pos = 3, cex = 0.85)
}

mtext("Fecha estimada por éxito, separando si pertenece a serie", outer = TRUE, cex = 1.1)

# leyenda (una sola vez)
legend("topleft", inset = 0.02,
       legend = levels(df$exito_f), fill = cols, bty = "n", cex = 0.9)

par(op)

tema vs tecnica

tema <- factor(df$tema)
tec  <- factor(df$tecnica)  # niveles: oleo/mixta/otras (o los que tengas)

tab  <- table(tema, tec)
prop <- prop.table(tab, 1)        # cada tema suma 1
n_tema <- rowSums(tab)

# Ordenar temas por n (de mayor a menor)
ord <- order(n_tema, decreasing = TRUE)
prop <- prop[ord, , drop = FALSE]
n_tema <- n_tema[ord]

# Etiquetas más legibles
tema_lab <- rownames(prop)
tema_lab <- gsub("_", "\n", tema_lab)  # corta por guiones bajos

# Colores (uno por técnica)
cols <- rainbow(ncol(prop))
names(cols) <- colnames(prop)

op <- par(no.readonly = TRUE)

# 2 paneles: gráfico + leyenda (así NO se pisa nunca)
layout(matrix(c(1,2), 1, 2), widths = c(4.8, 1.6))

par(mar = c(5, 12, 4, 1) + 0.1, xpd = NA)
bp <- barplot(t(prop),
              horiz = TRUE,
              beside = FALSE,
              xlim = c(0, 1),
              las = 1,
              col = cols[colnames(prop)],
              names.arg = tema_lab,
              main = "Distribución de técnicas dentro de cada tema",
              xlab = "Proporción",
              ylab = "Tema",
              cex.names = 0.85)

# n al final de cada barra
text(x = 1.02, y = bp, labels = paste0("n=", n_tema), pos = 4, cex = 0.8)

# Panel de la leyenda
par(mar = c(0,0,0,0))
plot.new()
legend("center",
       legend = colnames(prop),
       fill = cols[colnames(prop)],
       bty = "n",
       cex = 1)

layout(1)
par(op)


# (opcional) tablas
tab
##                    tec
## tema                mixta oleo otras
##   bodegon_floral        0  324     1
##   caza_animales         2  104     0
##   historia_alegoria    23  232     3
##   mitologia             0  227     0
##   otros                14 1193     9
##   paisaje_lugares       1  880     3
##   proceso_obra          1  121     1
##   religioso            73 2349    90
##   retrato_corte         5  987     3
##   vida_cotidiana        4  385     0
round(prop, 3)
##                    tec
## tema                mixta  oleo otras
##   religioso         0.029 0.935 0.036
##   otros             0.012 0.981 0.007
##   retrato_corte     0.005 0.992 0.003
##   paisaje_lugares   0.001 0.995 0.003
##   vida_cotidiana    0.010 0.990 0.000
##   bodegon_floral    0.000 0.997 0.003
##   historia_alegoria 0.089 0.899 0.012
##   mitologia         0.000 1.000 0.000
##   proceso_obra      0.008 0.984 0.008
##   caza_animales     0.019 0.981 0.000

tema vs tecnica y exito

# ==== TEMA x TÉCNICA, separado por ÉXITO (2 paneles + leyenda aparte) ====

# (Opcional) para que se vea bien: abre ventana grande
dev.new(width = 13, height = 5)
# (Opcional alternativa) guardar bonito:
# png("tema_tecnica_exito.png", width=1800, height=700, res=140)

df$exito_f   <- factor(df$exito, levels=c(0,1), labels=c("No cumple","Sí cumple"))
df$tema_f    <- factor(df$tema)
df$tecnica_f <- factor(df$tecnica)

# tabla 3D: tema x técnica x éxito
tab3 <- with(df, table(tema_f, tecnica_f, exito_f))

# ordenar temas por N total (para que ambos paneles sean comparables)
tab_total <- apply(tab3, c(1,2), sum)
n_total   <- rowSums(tab_total)
ord <- order(n_total, decreasing = TRUE)

tab3 <- tab3[ord, , , drop=FALSE]
tema_levels <- dimnames(tab3)[[1]]

# etiquetas tema más legibles
tema_lab <- gsub("_", "\n", tema_levels)

# colores por técnica (automático, pero fijo)
cols <- rainbow(nlevels(df$tecnica_f))
names(cols) <- levels(df$tecnica_f)

# preparar proporciones dentro de cada tema, por panel de éxito
prop_list <- vector("list", length(levels(df$exito_f)))
n_list    <- vector("list", length(levels(df$exito_f)))

for (k in seq_along(levels(df$exito_f))) {
  tab_k <- tab3[,,k]
  n_k   <- rowSums(tab_k)
  prop_k <- prop.table(tab_k, 1)   # cada tema suma 1
  prop_k[is.na(prop_k)] <- 0
  prop_list[[k]] <- prop_k
  n_list[[k]] <- n_k
}

op <- par(no.readonly = TRUE)

# layout: panel1 | panel2 | leyenda
layout(matrix(c(1,2,3), 1, 3), widths = c(5.2, 5.2, 1.7))
par(oma=c(0,0,2,0))  # margen externo para título general

for (k in seq_along(levels(df$exito_f))) {

  # margen izq grande solo en el primer panel (para que se lean los temas)
  par(mar = c(4.5, ifelse(k==1, 12, 2), 3, 1) + 0.1, xpd = NA)

  bp <- barplot(t(prop_list[[k]]),
                horiz = TRUE,
                beside = FALSE,
                col = cols[colnames(prop_list[[k]])],
                xlim = c(0,1),
                las = 1,
                names.arg = if (k==1) tema_lab else rep("", length(tema_lab)),
                cex.names = 0.85,
                cex.axis = 0.9,
                main = paste("Éxito:", levels(df$exito_f)[k]),
                xlab = "Proporción",
                ylab = if (k==1) "Tema" else "")

  # n por tema (a la derecha)
  text(x = 1.02, y = bp, labels = paste0("n=", n_list[[k]]), pos = 4, cex = 0.75)
}

# panel leyenda (aparte)
par(mar=c(0,0,0,0))
plot.new()
legend("center",
       legend = levels(df$tecnica_f),
       fill = cols[levels(df$tecnica_f)],
       bty = "n",
       cex = 1)

mtext("Distribución de técnicas dentro de cada tema (separado por éxito)", outer=TRUE, cex=1.1)

layout(1)
par(op)

# if (dev.cur() != 1) dev.off()  # <-- descomenta si usaste png()

##area vs fecha

plot(df$fecha_est, log(df$area),
     pch=16, cex=0.5,
     xlab="fecha_est", ylab="log(area)",
     main="Área vs fecha_est")
lines(lowess(df$fecha_est, log(df$area)), lwd=2)

La línea LOWESS es la tendencia: como está casi plana (ligeramente hacia abajo), no parece que el área cambie mucho con la fecha (relación débil o casi nula). Las “rayas verticales” salen porque muchos años se repiten.

# Asegura exito como factor con etiquetas
df$exito_f <- factor(df$exito, levels=c(0,1), labels=c("No cumple","Sí cumple"))

# Colores por exito
col_ex <- ifelse(df$exito_f == "Sí cumple", "green3", "red3")

# Scatter (con jitter suave en X para que no se monten tanto)
x <- jitter(df$fecha_est, amount = 0.25)
y <- log(df$area)

plot(x, y,
     pch = 16, cex = 0.5,
     col = col_ex,
     xlab = "fecha_est",
     ylab = "log(area+1)",
     main = "Área vs fecha_est (coloreado por éxito)")

legend("topright",
       legend = c("No cumple","Sí cumple"),
       col = c("red3","green3"),
       pch = 16, bty = "n")

# Tendencia global
lines(lowess(df$fecha_est, y), lwd = 2)

# (Opcional) 2 tendencias: una por cada exito
lines(lowess(df$fecha_est[df$exito_f=="No cumple"], y[df$exito_f=="No cumple"]), lwd=2, col="red3")
lines(lowess(df$fecha_est[df$exito_f=="Sí cumple"], y[df$exito_f=="Sí cumple"]), lwd=2, col="green3")

En el gráfico, cada punto es una obra: el eje X es la fecha estimada y el eje Y es el tamaño (área) en escala logarítmica; los puntos verdes son las obras que sí cumplen y los rojos las que no cumplen. La idea es ver si “cumplir” se asocia a obras más grandes o a ciertas épocas, pero como las nubes de puntos se mezclan mucho y las líneas de tendencia (verde y roja) van muy parecidas, no se ve una diferencia clara: a lo sumo, la línea verde queda un pelín por encima en algunos tramos, lo que sugeriría que las que “sí cumplen” podrían ser ligeramente más grandes, pero la diferencia es pequeña y no parece que con fecha + área puedas predecir bien el éxito.

##area por categorías (tam_cat / orientacion / soporte / tecnica) Para ver diferencias claras de tamaño (y outliers) por grupo.

boxplot(log(df$area+1) ~ df$orientacion, las=2,
        main="log(area+1) por orientación", xlab="orientación", ylab="log(area+1)")

boxplot(log(df$area+1) ~ df$soporte_grp, las=2,
        main="log(area+1) por soporte", xlab="soporte", ylab="log(area+1)")

En el boxplot de log(area+1) por orientación, lo que se ve es que las diferencias entre “horizontal”, “vertical” y “cuadrado” no son enormes: las medianas están bastante parecidas y las cajas se solapan mucho. Aun así, parece que las horizontales tienden a tener un área “típica” un pelín más alta (la línea del medio está algo más arriba) y en vertical aparecen más valores muy pequeños (puntitos bajos), o sea, hay más cuadros verticales con áreas muy pequeñas.

En el boxplot de log(area+1) por soporte, aquí sí se aprecian diferencias más claras entre categorías: “Mural” y “Lienzo” suelen tener áreas más grandes (la caja y la mediana están más arriba), mientras que “Metal” y “Otros” suelen ser más pequeños (medianas más bajas). “Tabla/Panel” queda en medio, y en casi todos los soportes hay algunos cuadros enormes (puntos altos), pero son pocos y por eso salen como “outliers”.

# Etiquetas de éxito
df$exito_f <- factor(df$exito, levels=c(0,1), labels=c("No cumple","Sí cumple"))

# Nos quedamos solo con NO-cuadrados
df2 <- subset(df, orientacion != "cuadrado" & !is.na(area))

# Quitar niveles vacíos ("cuadrado" desaparece de verdad)
df2$orientacion <- droplevels(factor(df2$orientacion))
df2$exito_f      <- droplevels(df2$exito_f)

# Grupo = orientacion + exito (sin niveles vacíos)
grp <- interaction(df2$orientacion, df2$exito_f, sep="\n", drop=TRUE)

# Color por grupo (rojo = No cumple, verde = Sí cumple)
col_grp <- ifelse(grepl("No cumple", levels(grp)), "red", "green")

par(mar=c(9,4,4,2)+0.1)
boxplot(log(df2$area + 1) ~ grp,
        las=2,
        col=col_grp,
        main="log(area+1) por orientación y éxito (sin cuadrados)",
        ylab="log(area+1)",
        xlab="")

legend("topright", legend=c("No cumple","Sí cumple"), fill=c("red","green"), bty="n")

df$exito_f <- factor(df$exito, levels=c(0,1), labels=c("No cumple","Sí cumple"))

# ¿Cuántos "cuadrado" hay y cuántos de esos salen "Sí cumple"?
with(df, table(orientacion, exito_f))
##             exito_f
## orientacion  No cumple Sí cumple
##   horizontal      2559       442
##   vertical        3594       407
##   cuadrado          33         0
# Mira las razones SOLO de los cuadrados que "sí cumplen"
idx <- df$orientacion == "cuadrado" & df$exito_f == "Sí cumple"
summary(df$razon[idx])
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
## 
head(df$razon[idx], 20)
## numeric(0)
# Y mira cómo son las razones en TODOS los cuadrados
summary(df$razon[df$orientacion=="cuadrado"])
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##       1       1       1       1       1       1
# =========================
# 2) log(area) ~ soporte_grp + exito
# =========================
par(mar=c(9,5,4,2)+0.1)

k2 <- length(levels(df$soporte_grp))

boxplot(y ~ df$soporte_grp * df$exito_f,
        col  = rep(cols_ex, times = k2),
        xaxt = "n",
        las  = 1,
        main = "log(area) por soporte y éxito",
        ylab = "log(area)",
        xlab = "")

axis(1,
     at = seq(1.5, by = 2, length.out = k2),
     labels = levels(df$soporte_grp),
     las = 2)

abline(v = seq(2.5, by = 2, length.out = k2-1), col = "gray80", lty = 2)

legend("topright", legend = levels(df$exito_f), fill = cols_ex, bty = "n")

par(op)

#tipo autor

# Factores “bonitos” (run once)
df$exito_f <- factor(df$exito, levels = c(0,1), labels = c("No cumple","Sí cumple"))
df$tipo_autor_f <- factor(df$tipo_autor)
df$orientacion_f <- factor(df$orientacion)
df$soporte_f <- factor(df$soporte_grp)
df$tecnica_f <- factor(df$tecnica)
df$tema_f <- factor(df$tema)

# serie y sop_montaje (si vienen como 0/1 numéricos)
if (is.numeric(df$serie) || is.integer(df$serie)) {
  df$serie_f <- factor(df$serie, levels = c(0,1),
                       labels = c("No pertenece a serie","Pertenece a serie"))
} else {
  df$serie_f <- factor(df$serie)
}

if (is.numeric(df$sop_montaje) || is.integer(df$sop_montaje)) {
  df$sop_montaje_f <- factor(df$sop_montaje, levels = c(0,1),
                             labels = c("No montaje","Sí montaje"))
} else {
  df$sop_montaje_f <- factor(df$sop_montaje)
}

# tam_cat ya lo tienes como ordered; lo usamos tal cual

############################################################
# 0) SETUP (ejecuta 1 vez)
############################################################

df$exito_f <- factor(df$exito, levels=c(0,1), labels=c("No cumple","Sí cumple"))
df$tipo_autor_f <- factor(df$tipo_autor)

# tam_cat: si está roto (todo NA), lo reconstruimos desde area
if ("tam_cat" %in% names(df)) {
  if (all(is.na(df$tam_cat))) {
    qs <- quantile(df$area, probs=c(1/3, 2/3), na.rm=TRUE)
    df$tam_cat <- cut(df$area,
                      breaks=c(-Inf, qs[1], qs[2], Inf),
                      labels=c("pequeno","mediano","grande"),
                      include.lowest=TRUE, ordered_result=TRUE)
  } else {
    df$tam_cat <- factor(as.character(df$tam_cat), ordered=TRUE)
    if (all(c("pequeno","mediano","grande") %in% levels(df$tam_cat))) {
      df$tam_cat <- factor(df$tam_cat, levels=c("pequeno","mediano","grande"), ordered=TRUE)
    }
  }
}

# serie y sop_montaje por si vienen como 0/1 numérico
if ("serie" %in% names(df) && (is.numeric(df$serie) || is.integer(df$serie))) {
  df$serie <- factor(df$serie, levels=c(0,1), labels=c("No serie","Sí serie"))
} else if ("serie" %in% names(df)) df$serie <- factor(df$serie)

if ("sop_montaje" %in% names(df) && (is.numeric(df$sop_montaje) || is.integer(df$sop_montaje))) {
  df$sop_montaje <- factor(df$sop_montaje, levels=c(0,1), labels=c("No montaje","Sí montaje"))
} else if ("sop_montaje" %in% names(df)) df$sop_montaje <- factor(df$sop_montaje)

# factores típicos
if ("orientacion" %in% names(df)) df$orientacion <- factor(df$orientacion)
if ("soporte_grp" %in% names(df)) df$soporte_grp <- factor(df$soporte_grp)
if ("tecnica" %in% names(df)) df$tecnica <- factor(df$tecnica)
if ("tema" %in% names(df)) df$tema <- factor(df$tema)
if ("fecha_est" %in% names(df)) df$fecha_est <- as.integer(df$fecha_est)
if ("area" %in% names(df)) df$area <- as.numeric(df$area)

# colapsar categorías si hay muchísimas (para que se lea)
collapse_top <- function(f, top=12){
  f <- factor(f)
  tab <- sort(table(f), decreasing=TRUE)
  keep <- names(tab)[seq_len(min(top, length(tab)))]
  out <- as.character(f)
  out[!(out %in% keep)] <- "Otros"
  factor(out, levels=c(keep, "Otros"))
}


############################################################
# 3) GRÁFICO 1: tipo_autor vs exito (ya incluye exito)
############################################################
{
  tab <- table(df$tipo_autor_f, df$exito_f)
  prop <- prop.table(tab, 1)
  n <- rowSums(tab)

  cols <- c("red","green")
  par(mar=c(9,4,4,2)+0.1)
  bp <- barplot(t(prop), beside=FALSE, ylim=c(0,1), las=2, col=cols,
                main="Éxito dentro de cada tipo de autor",
                ylab="Proporción", xlab="Tipo de autor")
  legend("topright", legend=levels(df$exito_f), fill=cols, bty="n")
  text(x=bp, y=1.02, labels=paste0("n=", n), xpd=TRUE, cex=0.8)
}

############################################################
# 4) LOS OTROS 8: tipo_autor vs X, separado por exito
############################################################

tipo de autor vs tema

tab <- table(df$tipo_autor, df$tema)
prop <- prop.table(tab, 1)
n <- rowSums(tab)

tema_levels <- colnames(prop)
cols <- grDevices::rainbow(length(tema_levels))

par(mar=c(9,4,4,12)+0.1)  # extra a la derecha para la leyenda
bp <- barplot(t(prop),
              beside=FALSE, ylim=c(0,1), las=2,
              col=cols,
              main="Distribución de temas dentro de cada tipo de autor",
              ylab="Proporción", xlab="Tipo de autor")
text(x=bp, y=1.02, labels=paste0("n=", n), xpd=TRUE, cex=0.8)

legend("topright", inset=c(-0.35,0), xpd=TRUE,
       legend=tema_levels, fill=cols, bty="n", cex=0.8)

tab
##          
##           bodegon_floral caza_animales historia_alegoria mitologia otros
##   anonimo             41             3                19        18    57
##   hombre             263           103               205       195  1126
##   mujer               15             0                 0         0    17
##   varios               6             0                34        14    16
##          
##           paisaje_lugares proceso_obra religioso retrato_corte vida_cotidiana
##   anonimo              81            8       319            89             26
##   hombre              778          110      2136           886            359
##   mujer                 7            3         6            11              0
##   varios               18            2        51             9              4
round(prop, 3)
##          
##           bodegon_floral caza_animales historia_alegoria mitologia otros
##   anonimo          0.062         0.005             0.029     0.027 0.086
##   hombre           0.043         0.017             0.033     0.032 0.183
##   mujer            0.254         0.000             0.000     0.000 0.288
##   varios           0.039         0.000             0.221     0.091 0.104
##          
##           paisaje_lugares proceso_obra religioso retrato_corte vida_cotidiana
##   anonimo           0.123        0.012     0.483         0.135          0.039
##   hombre            0.126        0.018     0.347         0.144          0.058
##   mujer             0.119        0.051     0.102         0.186          0.000
##   varios            0.117        0.013     0.331         0.058          0.026

tipo_auto vs tema con exito

# ===== tipo_autor vs tema, separado por exito (2 paneles + leyenda aparte) =====

# Asegurar factores
df$exito_f <- factor(df$exito, levels=c(0,1), labels=c("No cumple","Sí cumple"))
df$tipo_autor_f <- factor(df$tipo_autor)
df$tema_f <- factor(df$tema)

# Tabla 3D: autor x tema x exito
tab3 <- with(df, table(tipo_autor_f, tema_f, exito_f))

# Ordenar temas por frecuencia total (para que sea comparable en ambos paneles)
tab_total <- apply(tab3, c(1,2), sum)     # autor x tema (sumando exito)
tema_tot  <- colSums(tab_total)           # total por tema
ord_tema  <- order(tema_tot, decreasing = TRUE)

tab3 <- tab3[, ord_tema, , drop=FALSE]
tema_levels <- dimnames(tab3)[[2]]

# Etiquetas tema (si quieres partirlas)
tema_lab <- gsub("_", "\n", tema_levels)

# Colores por tema (muchos temas -> muchos colores)
cols <- grDevices::rainbow(length(tema_levels))
names(cols) <- tema_levels

op <- par(no.readonly = TRUE)

# 3 paneles: No cumple | Sí cumple | Leyenda
layout(matrix(c(1,2,3), 1, 3), widths = c(5.2, 5.2, 2.2))
par(oma=c(0,0,2,0))

for (k in 1:length(levels(df$exito_f))) {

  tab_k <- tab3[, , k, drop=FALSE][,,1]          # autor x tema para ese exito
  prop  <- prop.table(tab_k, 1)                   # dentro de cada tipo_autor
  prop[is.na(prop)] <- 0
  n_aut <- rowSums(tab_k)

  par(mar=c(9,4,4,1)+0.1, xpd=NA)

  bp <- barplot(t(prop),
                beside = FALSE,
                ylim = c(0,1),
                las = 2,
                col = cols[colnames(prop)],
                main = paste("Éxito:", levels(df$exito_f)[k]),
                ylab = "Proporción",
                xlab = "Tipo de autor")

  text(x=bp, y=1.02, labels=paste0("n=", n_aut), xpd=TRUE, cex=0.8)
}

# Panel leyenda aparte
par(mar=c(0,0,0,0))
plot.new()
legend("center",
       legend = tema_lab,
       fill = cols[tema_levels],
       bty = "n",
       cex = 0.75)

mtext("Distribución de temas dentro de cada tipo_autor (separado por éxito)", outer=TRUE, cex=1.1)

layout(1)
par(op)

##tipo_autor vs tecnica

tab <- table(df$tipo_autor, df$tecnica)
prop <- prop.table(tab, 1)
n <- rowSums(tab)

tec_levels <- colnames(prop)
cols <- grDevices::rainbow(length(tec_levels))

par(mar=c(9,4,4,10)+0.1)
bp <- barplot(t(prop),
              beside=FALSE, ylim=c(0,1), las=2,
              col=cols,
              main="Distribución de técnicas dentro de cada tipo de autor",
              ylab="Proporción", xlab="Tipo de autor")
text(x=bp, y=1.02, labels=paste0("n=", n), xpd=TRUE, cex=0.8)

legend("topright", inset=c(-0.25,0), xpd=TRUE,
       legend=tec_levels, fill=cols, bty="n", cex=0.9)

tab
##          
##           mixta oleo otras
##   anonimo     8  614    39
##   hombre     90 6006    65
##   mujer       0   59     0
##   varios     25  123     6
round(prop, 3)
##          
##           mixta  oleo otras
##   anonimo 0.012 0.929 0.059
##   hombre  0.015 0.975 0.011
##   mujer   0.000 1.000 0.000
##   varios  0.162 0.799 0.039

##tipo_autor vs tecnica con exito

# ===== tipo_autor vs tecnica, separado por exito (2 paneles + leyenda aparte) =====

# Asegurar factores
df$exito_f <- factor(df$exito, levels=c(0,1), labels=c("No cumple","Sí cumple"))
df$tipo_autor_f <- factor(df$tipo_autor)
df$tecnica_f <- factor(df$tecnica)

# Tabla 3D: autor x técnica x exito
tab3 <- with(df, table(tipo_autor_f, tecnica_f, exito_f))

# Ordenar técnicas por frecuencia total (para comparar igual en ambos paneles)
tab_total <- apply(tab3, c(1,2), sum)     # autor x técnica (sumando exito)
tec_tot   <- colSums(tab_total)           # total por técnica
ord_tec   <- order(tec_tot, decreasing = TRUE)

tab3 <- tab3[, ord_tec, , drop=FALSE]
tec_levels <- dimnames(tab3)[[2]]

# Etiquetas técnica (si quieres partirlas)
tec_lab <- gsub("_", "\n", tec_levels)

# Colores por técnica
cols <- grDevices::rainbow(length(tec_levels))
names(cols) <- tec_levels

op <- par(no.readonly = TRUE)

# 3 paneles: No cumple | Sí cumple | Leyenda
layout(matrix(c(1,2,3), 1, 3), widths = c(5.2, 5.2, 2.2))
par(oma=c(0,0,2,0))

for (k in 1:length(levels(df$exito_f))) {

  tab_k <- tab3[, , k, drop=FALSE][,,1]          # autor x técnica para ese exito
  prop  <- prop.table(tab_k, 1)                   # dentro de cada tipo_autor
  prop[is.na(prop)] <- 0
  n_aut <- rowSums(tab_k)

  par(mar=c(9,4,4,1)+0.1, xpd=NA)

  bp <- barplot(t(prop),
                beside = FALSE,
                ylim = c(0,1),
                las = 2,
                col = cols[colnames(prop)],
                main = paste("Éxito:", levels(df$exito_f)[k]),
                ylab = "Proporción",
                xlab = "Tipo de autor")

  text(x=bp, y=1.02, labels=paste0("n=", n_aut), xpd=TRUE, cex=0.8)
}

# Panel leyenda aparte
par(mar=c(0,0,0,0))
plot.new()
legend("center",
       legend = tec_lab,
       fill = cols[tec_levels],
       bty = "n",
       cex = 0.9)

mtext("Distribución de técnicas dentro de cada tipo_autor (separado por éxito)", outer=TRUE, cex=1.1)

layout(1)
par(op)

##tipo_autor vs soporte_grp

tab <- table(df$tipo_autor, df$soporte_grp)
prop <- prop.table(tab, 1)
n <- rowSums(tab)

sup_levels <- colnames(prop)
cols <- grDevices::rainbow(length(sup_levels))

par(mar=c(9,4,4,10)+0.1)
bp <- barplot(t(prop),
              beside=FALSE, ylim=c(0,1), las=2,
              col=cols,
              main="Distribución de soportes dentro de cada tipo de autor",
              ylab="Proporción", xlab="Tipo de autor")
text(x=bp, y=1.02, labels=paste0("n=", n), xpd=TRUE, cex=0.8)

legend("topright", inset=c(-0.25,0), xpd=TRUE,
       legend=sup_levels, fill=cols, bty="n", cex=0.9)

tab
##          
##           Lienzo Metal Mural Otros Tabla/Panel
##   anonimo    501    21    25     3         111
##   hombre    4928   128    21   112         972
##   mujer       51     2     0     0           6
##   varios      62     3     4    23          62
round(prop, 3)
##          
##           Lienzo Metal Mural Otros Tabla/Panel
##   anonimo  0.758 0.032 0.038 0.005       0.168
##   hombre   0.800 0.021 0.003 0.018       0.158
##   mujer    0.864 0.034 0.000 0.000       0.102
##   varios   0.403 0.019 0.026 0.149       0.403

##tipo_autor vs soporte_grp con exito

# ===== tipo_autor vs soporte_grp, separado por exito (2 paneles + leyenda aparte) =====

# Asegurar factores
df$exito_f <- factor(df$exito, levels=c(0,1), labels=c("No cumple","Sí cumple"))
df$tipo_autor_f <- factor(df$tipo_autor)
df$soporte_f <- factor(df$soporte_grp)

# Tabla 3D: autor x soporte x exito
tab3 <- with(df, table(tipo_autor_f, soporte_f, exito_f))

# Ordenar soportes por frecuencia total (para comparar igual en ambos paneles)
tab_total <- apply(tab3, c(1,2), sum)      # autor x soporte (sumando exito)
sup_tot   <- colSums(tab_total)            # total por soporte
ord_sup   <- order(sup_tot, decreasing = TRUE)

tab3 <- tab3[, ord_sup, , drop=FALSE]
sup_levels <- dimnames(tab3)[[2]]

# Etiquetas soporte (partir las largas)
sup_lab <- sup_levels
sup_lab <- gsub("Papel/Vitela", "Papel/\nVitela", sup_lab)
sup_lab <- gsub("Tabla/Panel", "Tabla/\nPanel", sup_lab)

# Colores por soporte
cols <- grDevices::rainbow(length(sup_levels))
names(cols) <- sup_levels

op <- par(no.readonly = TRUE)

# 3 paneles: No cumple | Sí cumple | Leyenda
layout(matrix(c(1,2,3), 1, 3), widths = c(5.2, 5.2, 2.2))
par(oma=c(0,0,2,0))

for (k in 1:length(levels(df$exito_f))) {

  tab_k <- tab3[, , k, drop=FALSE][,,1]         # autor x soporte para ese exito
  prop  <- prop.table(tab_k, 1)                  # dentro de cada tipo_autor
  prop[is.na(prop)] <- 0
  n_aut <- rowSums(tab_k)

  par(mar=c(9,4,4,1)+0.1, xpd=NA)

  bp <- barplot(t(prop),
                beside = FALSE,
                ylim = c(0,1),
                las = 2,
                col = cols[colnames(prop)],
                main = paste("Éxito:", levels(df$exito_f)[k]),
                ylab = "Proporción",
                xlab = "Tipo de autor")

  text(x=bp, y=1.02, labels=paste0("n=", n_aut), xpd=TRUE, cex=0.8)
}

# Panel leyenda aparte
par(mar=c(0,0,0,0))
plot.new()
legend("center",
       legend = sup_lab,
       fill = cols[sup_levels],
       bty = "n",
       cex = 0.9)

mtext("Distribución de soportes dentro de cada tipo_autor (separado por éxito)", outer=TRUE, cex=1.1)

layout(1)
par(op)

##tam_cat vs tipo de autor

## 1) Diagnóstico rápido: ¿tam_cat está roto?
table(df$tam_cat, useNA = "ifany")
## 
## pequeno mediano  grande 
##    2345    2345    2345
## 2) Arreglo automático:
##    - Si tam_cat tiene valores: lo re-factoriza bien
##    - Si tam_cat está TODO NA: lo reconstruye desde area (pequeño/mediano/grande)

tam_raw <- df$tam_cat

if (all(is.na(tam_raw))) {
  # RECREAR tam_cat desde area (terciles)
  qs <- quantile(df$area, probs = c(1/3, 2/3), na.rm = TRUE)
  df$tam_cat <- cut(df$area,
                    breaks = c(-Inf, qs[1], qs[2], Inf),
                    labels = c("pequeno", "mediano", "grande"),
                    include.lowest = TRUE, ordered_result = TRUE)
} else {
  # REFACTOR usando los valores reales que existen (y sin inventar levels)
  df$tam_cat <- factor(as.character(tam_raw))
}

## (Opcional) si quieres un orden concreto cuando son pequeno/mediano/grande:
if (all(c("pequeno","mediano","grande") %in% levels(df$tam_cat))) {
  df$tam_cat <- factor(df$tam_cat, levels = c("pequeno","mediano","grande"), ordered = TRUE)
}

## 3) GRAFICO tipo_autor vs tam_cat (100% dentro de cada autor)
df$tipo_autor_f <- factor(df$tipo_autor)

tab <- table(df$tipo_autor_f, df$tam_cat)
prop <- prop.table(tab, 1)
n <- rowSums(tab)

tam_levels <- colnames(prop)
cols <- grDevices::heat.colors(length(tam_levels))

par(mar=c(9,4,4,10)+0.1)
bp <- barplot(t(prop),
              beside = FALSE, ylim = c(0,1), las = 2,
              col = cols,
              main = "Distribución de tamaños (tam_cat) dentro de cada tipo de autor",
              ylab = "Proporción", xlab = "Tipo de autor")

text(x = bp, y = 1.02, labels = paste0("n=", n), xpd = TRUE, cex = 0.8)

legend("topright", inset=c(-0.25,0), xpd=TRUE,
       legend = tam_levels, fill = cols, bty = "n", cex = 0.9)

tab
##          
##           pequeno mediano grande
##   anonimo     237     225    199
##   hombre     2051    2026   2084
##   mujer        24      26      9
##   varios       33      68     53
round(prop, 3)
##          
##           pequeno mediano grande
##   anonimo   0.359   0.340  0.301
##   hombre    0.333   0.329  0.338
##   mujer     0.407   0.441  0.153
##   varios    0.214   0.442  0.344

##tam_cat vs tipo de autor con exito

##tipo_autor vs orientacion

tab <- table(df$tipo_autor, df$orientacion)
prop <- prop.table(tab, 1)
n <- rowSums(tab)

ori_levels <- colnames(prop)
cols <- c("gray50","orange2","skyblue3")[seq_along(ori_levels)]  # ajusta si quieres

par(mar=c(9,4,4,2)+0.1)
bp <- barplot(t(prop),
              beside=FALSE, ylim=c(0,1), las=2,
              col=cols,
              main="Distribución de orientación dentro de cada tipo de autor",
              ylab="Proporción", xlab="Tipo de autor")
legend("topright", legend=ori_levels, fill=cols, bty="n")
text(x=bp, y=1.02, labels=paste0("n=", n), xpd=TRUE, cex=0.8)

tab
##          
##           horizontal vertical cuadrado
##   anonimo        263      394        4
##   hombre        2650     3482       29
##   mujer           15       44        0
##   varios          73       81        0
round(prop, 3)
##          
##           horizontal vertical cuadrado
##   anonimo      0.398    0.596    0.006
##   hombre       0.430    0.565    0.005
##   mujer        0.254    0.746    0.000
##   varios       0.474    0.526    0.000

##tipo_autor vs tam_cat

## 1) Diagnóstico rápido: ¿tam_cat está roto?
table(df$tam_cat, useNA = "ifany")
## 
## pequeno mediano  grande 
##    2345    2345    2345
## 2) Arreglo automático:
##    - Si tam_cat tiene valores: lo re-factoriza bien
##    - Si tam_cat está TODO NA: lo reconstruye desde area (pequeño/mediano/grande)

tam_raw <- df$tam_cat

if (all(is.na(tam_raw))) {
  # RECREAR tam_cat desde area (terciles)
  qs <- quantile(df$area, probs = c(1/3, 2/3), na.rm = TRUE)
  df$tam_cat <- cut(df$area,
                    breaks = c(-Inf, qs[1], qs[2], Inf),
                    labels = c("pequeno", "mediano", "grande"),
                    include.lowest = TRUE, ordered_result = TRUE)
} else {
  # REFACTOR usando los valores reales que existen (y sin inventar levels)
  df$tam_cat <- factor(as.character(tam_raw))
}

## (Opcional) si quieres un orden concreto cuando son pequeno/mediano/grande:
if (all(c("pequeno","mediano","grande") %in% levels(df$tam_cat))) {
  df$tam_cat <- factor(df$tam_cat, levels = c("pequeno","mediano","grande"), ordered = TRUE)
}

## 3) GRAFICO tipo_autor vs tam_cat (100% dentro de cada autor)
df$tipo_autor_f <- factor(df$tipo_autor)

tab <- table(df$tipo_autor_f, df$tam_cat)
prop <- prop.table(tab, 1)
n <- rowSums(tab)

tam_levels <- colnames(prop)
cols <- grDevices::heat.colors(length(tam_levels))

par(mar=c(9,4,4,10)+0.1)
bp <- barplot(t(prop),
              beside = FALSE, ylim = c(0,1), las = 2,
              col = cols,
              main = "Distribución de tamaños (tam_cat) dentro de cada tipo de autor",
              ylab = "Proporción", xlab = "Tipo de autor")

text(x = bp, y = 1.02, labels = paste0("n=", n), xpd = TRUE, cex = 0.8)

legend("topright", inset=c(-0.25,0), xpd=TRUE,
       legend = tam_levels, fill = cols, bty = "n", cex = 0.9)

tab
##          
##           pequeno mediano grande
##   anonimo     237     225    199
##   hombre     2051    2026   2084
##   mujer        24      26      9
##   varios       33      68     53
round(prop, 3)
##          
##           pequeno mediano grande
##   anonimo   0.359   0.340  0.301
##   hombre    0.333   0.329  0.338
##   mujer     0.407   0.441  0.153
##   varios    0.214   0.442  0.344

##tipo_autor vs area (boxplot de log(area))

y <- log(df$area)

par(mar=c(9,4,4,2)+0.1)
boxplot(y ~ df$tipo_autor, las=2,
        main="log(area) por tipo de autor",
        xlab="Tipo de autor", ylab="log(area)")

## tipo_autor vs fecha_est

par(mar=c(9,4,4,2)+0.1)
boxplot(df$fecha_est ~ df$tipo_autor, las=2,
        main="fecha_est por tipo de autor",
        xlab="Tipo de autor", ylab="fecha_est (año)")

##tipo_autor vs serie

tab <- table(df$tipo_autor, df$serie)
prop <- prop.table(tab, 1)
n <- rowSums(tab)

ser_levels <- colnames(prop)
cols <- c("gray70","steelblue3")[seq_along(ser_levels)]

par(mar=c(9,4,4,2)+0.1)
bp <- barplot(t(prop),
              beside=FALSE, ylim=c(0,1), las=2,
              col=cols,
              main="Serie dentro de cada tipo de autor",
              ylab="Proporción", xlab="Tipo de autor")
legend("topright", legend=ser_levels, fill=cols, bty="n")
text(x=bp, y=1.02, labels=paste0("n=", n), xpd=TRUE, cex=0.8)

tab
##          
##              0    1
##   anonimo  528  133
##   hombre  4956 1205
##   mujer     55    4
##   varios    89   65
round(prop, 3)
##          
##               0     1
##   anonimo 0.799 0.201
##   hombre  0.804 0.196
##   mujer   0.932 0.068
##   varios  0.578 0.422